<template>
  <up-popup
    :show="show"
    mode="bottom"
    :popup="false"
    :mask="true"
    :closeable="true"
    :safeAreaInsetBottom="true"
    closeIconColor="#ffffff"
    zIndex="9"
    :maskCloseAble="true"
    @close="onClose">
    <up-tabs
      v-if="show"
      ref="tabs"
      :list="tabList"
      :scrollable="true"
      :current="tabsIndex"
      @change="onTabsChange" />
    <view class="area-box">
      <view class="u-flex" :class="{ change: tabsIndex > 1 }">
        <view class="area-item">
          <view class="u-padding-10 u-bg-gray" style="height: 100%;">
            <scroll-view :scrollY="true" style="height: 100%">
              <up-cell-group>
                <up-cell
                  v-for="(item, index) in provinces"
                  :key="index"
                  :title="item.label"
                  :arrow="false"
                  :index="index"
                  @click="provinceChange(index)">
                  <template #right-icon>
                    <up-icon
                      v-if="state.isChooseP && pIndex === index"
                      size="17"
                      color="#1269FF"
                      name="checkbox-mark" />
                  </template>
                </up-cell>
              </up-cell-group>
            </scroll-view>
          </view>
        </view>
        <view class="area-item">
          <view class="u-padding-10 u-bg-gray" style="height: 100%;">
            <scroll-view :scrollY="true" style="height: 100%">
              <up-cell-group v-if="state.isChooseP">
                <up-cell
                  v-for="(item, index) in cities"
                  :key="index"
                  :title="item.label"
                  :arrow="false"
                  :index="index"
                  @click="cityChange(index)">
                  <template #right-icon>
                    <up-icon
                      v-if="state.isChooseC && cIndex === index"
                      size="17"
                      color="#1269FF"
                      name="checkbox-mark" />
                  </template>
                </up-cell>
              </up-cell-group>
            </scroll-view>
          </view>
        </view>
        <view class="area-item">
          <view class="u-padding-10 u-bg-gray" style="height: 100%;">
            <scroll-view :scrollY="true" style="height: 100%">
              <up-cell-group v-if="state.isChooseC">
                <up-cell
                  v-for="(item, index) in areas"
                  :key="index"
                  :title="item.label"
                  :arrow="false"
                  :index="index"
                  @click="areaChange(index)">
                  <template #right-icon>
                    <up-icon
                      v-if="state.isChooseA && aIndex === index"
                      size="17"
                      color="#1269FF"
                      name="checkbox-mark" />
                  </template>
                </up-cell>
              </up-cell-group>
            </scroll-view>
          </view>
        </view>
      </view>
    </view>
  </up-popup>
</template>

<script lang="ts" setup>
  import { computed, defineEmits, defineProps, onMounted, reactive, ref, withDefaults } from 'vue'
  import { areas as areaData, cities as cityData, provinces as provinceData } from './data'

  type LabelValue = {
    label: string;
    value: string;
  }

  type ChangeResult = {
    province: LabelValue;
    city: LabelValue;
    area: LabelValue;
  }

  const emit = defineEmits<{
    (e: 'update:show', value: boolean): void,
    (e: 'change', value: ChangeResult): void,
  }>()

  const props = withDefaults(defineProps<{
    show?: boolean;
    // 默认显示的地区，可传类似["河北省", "秦皇岛市", "北戴河区"]
    defaultRegion?: string[];
    // 默认显示地区的编码，defaultRegion和areaCode同时存在，areaCode优先，可传类似["13", "1303", "130304"]
    areaCode?: string[];
  }>(), {
    show: false,
    defaultRegion: () => [],
    areaCode: () => [],
  })

  const provinces = ref(provinceData)
  const cities = ref(cityData[0])
  const areas = ref(areaData[0][0])

  // 省级下标
  const pIndex = ref(0)
  // 市级下标
  const cIndex = ref(0)
  // 区级下标
  const aIndex = ref(0)
  const tabsIndex = ref(0)

  const state = reactive({
    isChooseP: false, // 是否已经选择了省
    isChooseC: false, // 是否已经选择了市
    isChooseA: false, // 是否已经选择了区
  })

  const tabList = computed(() => {
    const tabsList = [{ name: '请选择' }]
    if (state.isChooseP) {
      tabsList[0].name = provinces.value[pIndex.value].label
      tabsList[1] = { name: '请选择' }
    }
    if (state.isChooseC) {
      tabsList[1].name = cities.value[cIndex.value].label
      tabsList[2] = { name: '请选择' }
    }
    if (state.isChooseA) {
      tabsList[2].name = areas.value[aIndex.value].label
    }
    return tabsList
  })

  const initialize = () => {
    if (props.areaCode.length === 3) {
      const [p, c, a] = props.areaCode
      setProvince('', p)
      setCity('', c)
      setArea('', a)
    } else if (props.defaultRegion.length === 3) {
      const [p, c, a] = props.defaultRegion
      setProvince(p, '')
      setCity(c, '')
      setArea(a, '')
    }
  }

  const onClose = () => {
    emit('update:show', false)
  }

  const onTabsChange = (index: number) => {
    tabsIndex.value = index
  }

  const setProvince = (label = '', value = '') => {
    provinces.value.map((v, k) => {
      if (value ? v.value === value : v.label === label) {
        provinceChange(k)
      }
    })
  }

  const setCity = (label = '', value = '') => {
    cities.value.map((v, k) => {
      if (value ? v.value === value : v.label === label) {
        cityChange(k)
      }
    })
  }

  const setArea = (label = '', value = '') => {
    areas.value.map((v, k) => {
      if (value ? v.value === value : v.label === label) {
        state.isChooseA = true
        aIndex.value = k
      }
    })
  }

  const provinceChange = (index: number) => {
    state.isChooseP = true
    state.isChooseC = false
    state.isChooseA = false
    pIndex.value = index
    cities.value = cityData[index]
    tabsIndex.value = 1
  }

  const cityChange = (index:number) => {
    state.isChooseC = true
    state.isChooseA = false
    cIndex.value = index
    areas.value = areaData[pIndex.value][index]
    tabsIndex.value = 2
  }

  const areaChange = (index: number) => {
    state.isChooseA = true
    aIndex.value = index
    const province = provinces.value[pIndex.value]
    const city = cities.value[cIndex.value]
    const area = areas.value[aIndex.value]

    emit('change', { province, city, area })
    onClose()
  }

  onMounted(() => {
    initialize()
  })
</script>

<style lang="scss" scoped>
	.u-flex {
		display: flex;
	}
	.u-padding-10 {
		padding: 10rpx;
	}
	.area-box {
		width: 100%;
		overflow: hidden;
		height: 800rpx;

		>view {
			width: 150%;
			transition: transform 0.3s ease-in-out 0s;
			transform: translateX(0);

			&.change {
				transform: translateX(-33.3333333%);
			}
		}

		.area-item {
			width: 33.3333333%;
			height: 800rpx;
		}
	}
</style>
